#pragma once

#include <stdint.h>
#include <float.h>
#include "base/core/point3.h"
#include "base/core/gamemath.h"
#include "Common/CharacterDefine.h"
class Creature;
class Monster;
class AbstractMonsterStateLogic;
class Map;

#define __PI		3.1415f
#define RAND_MAX1 (RAND_MAX)

enum AiTargetType
{
	AiTargetType_Player = 0,
	AiTargetType_Monster = 1,
	AiTargetType_ALl = 2,
};

class AiLogicUtility
{
public:
	//以targetPos为圆心，radius为半径的圆里，链接srcPos和targetPos的线，以线为中心找到一个半圆
	static Point3<float> GetRandomPosInStraightCircle180(uint32_t mapId, const Point3<float>& srcPos, const Point3<float>& targetPos, float radius); 
	static Point3<float> GetRandomPosInStraightCircle(uint32_t mapId, const Point3<float>& srcPos, const Point3<float>& targetPos, float radius, float angle);
	//在以srcPos为中心，以radiux为半径的圆里面找个位置
	static Point3<float> GetRandomPosInCircle(uint32_t mapId, const Point3<float>& srcPos, float radius); 
	//在以srcPos为中心，以radiux为半径的圆上找个位置
	static Point3<float> GetRandomPosOnCircle(uint32_t mapId, const Point3<float>& srcPos, float radius); 
	//在srcPos到targetPos的线上找到一个距离targetPos，radiux远的位置
	static Point3<float> GetPosInStraight(uint32_t mapId, const Point3<float>& srcPos, const Point3<float>& targetPos, float radius);
	static Point3<float> GetNearstPos(uint32_t mapId, const Point3<float>& srcPos);
	static bool GetNearstPos(uint32_t mapId, const Point3<float>& srcPos, Point3<float>& destPos);
	static Point3<float> GetNearstPos(Monster* pMonster);
	static bool ComputeTrackPoint(int mapId, const Point3<float>& srcPos, const Point3<float>& targetPos, const float fTrackRadius, Point3<float>& destPos);
	static bool GetDestAndAngle(Creature* pSrc, Creature* pTarget, Point3<float>& destPos, float& angle, int& area);
	static bool GetChasePoint(int mapId, const float fMinRange, const float fMaxRange, const Point3<float>& dest, const float angle, Point3<float>& chasePoint);
	static bool GetRandomPosInCircle(uint32_t mapId, const Point3<float>& srcPos, float radius, Point3<float>& destPos);//在以srcPos为中心，以radiux为半径的圆里面找个位置
	static bool GetRandomPosOnCircle(uint32_t mapId, const Point3<float>& srcPos, float radius, Point3<float>& destPos);//在以srcPos为中心，以radiux为半径的圆上找个位置
public:
	// 求两点所构成矢量的弧度值(返回0~2*pi的值，以z的正方向为0度)
	static float GetDotAngle(float x1, float z1, float x2, float z2)
	{
		float sx = x2 - x1;
		float sy = z2 - z1;
		float dict = ::sqrt(sx * sx + sy * sy);
		float a = 0.0f;

		if (!UtilFloatEqualZero(dict))
		{
			a = ::acos(sy/ dict);
		}

		if (sx < 0) a = -a;
		return UtilNormalizeAngle(a);
	}

	// 将-pi~pi的弧度值转换为0~2*pi的弧度值
	static float UtilNormalizeAngle(float angle)
	{
		float value = ::fmod(angle, MMO_PI2);
		if (value < 0)
		{
			value = value + MMO_PI2;
		}

		if (value < EPS && ::abs(angle) > MMO_PI)
		{
			value = MMO_PI2;
		}
		return value;
	}

	// 求angle1和angle2的角度差，返回0~pi的弧度值
	static float UtilGetAngleDiff(const float& angle1, const float& angle2)
	{
		const float norm_angle1 = UtilNormalizeAngle(angle1);
		const float norm_angle2 = UtilNormalizeAngle(angle2);

		float angle_diff = fabs(norm_angle1 - norm_angle2);
		if (angle_diff > MMO_PI)
		{
			angle_diff = MMO_PI2 - angle_diff;
		}

		return angle_diff;
	}
public:
	//// 判断两个浮点数是否可认为相等
	static bool UtilFloatEqual(float f1, float f2)
	{
		return (f1 < (f2 + EPS)) && (f1 > (f2 - EPS));
	}

	static bool UtilFloatEqualZero(float f)
	{
		return (f >= -EPS && f <= EPS);
	}

	static bool UtilDoubleEqualZero(double f)
	{
		return (f >= -FLT_EPSILON && f <= FLT_EPSILON);
	}
public:
	// 返回0-scale)的随机浮点数
	static float UtilRandomFloat(float scale)
	{
		static const float TMP = 1.0f / float(RAND_MAX1);

		if (scale <= 0.0f)
		{
			return 0.0f;
		}
		return (float(::rand()) * TMP * scale);
	}
};
